import { RepoLink, Link } from '@brillout/docpress'
import { UiFrameworkExtension } from '../../components'

The usual recommendation is to use Vike's `data()` hook for fetching initial data, and another dedicated tool for data mutations and subsequent data (such as pagination data).


## Initial data

For fetching the initial data of a page you can use Vike's `data()` hook, or you can use tools such as TanStack Query instead.

- <Link href="#data-hook" /><br/>
- <Link href="#tools" /><br/>

### `data()` hook

You can fetch the initial data of a page by using the <Link href="/data">Vike hook `data()`</Link> together with the <Link href="/useData">component hook `useData()`</Link>.

```js
// /pages/movies/@id/+data.js
// Environment: server

export { data }

import fetch from 'node-fetch'

async function data(pageContext) {
  const { id } = pageContext.routeParams
  const response = await fetch(`https://star-wars.brillout.com/api/films/${id}.json`)

  let movie = await response.json()
  // `movie` is serialized and passed to the client. Therefore, we pick only the
  // data the client needs in order to minimize what is sent over the network.
  movie = { title: movie.title, release_date: movie.release_date }

  // data() runs only on the server-side by default, we can therefore use ORM/SQL queries.
  /* With an ORM:
  const movies = await Movie.findAll({ select: ['title', 'release_date'] }) */
  /* With SQL:
  const movies = await sql.run('SELECT { title, release_date } FROM movies;') */

  return {
    movies
  }
}
```

> `pageContext` holds contextual information, see <Link href="/pageContext" />.

> The `@id` in the file path `/pages/movie/@id/+data.js` denotes a route parameter which value is available at `pageContext.routeParams.id`, see <Link href="/routing" />.

```js
// SomeComponent.js
// Environment: server, client

import { useData } from 'vike-react/useData'
/* Or:
import { useData } from 'vike-vue/useData'
import { useData } from 'vike-solid/useData'
*/

  // Inside a UI component
  const data = useData()
  const { name, price } = data
```

> `useData()` is implemented by the <UiFrameworkExtension name />. If you don't use <UiFrameworkExtension name noLink /> then see <Link href="/useData#without-vike-react-vue-solid" doNotInferSectionTitle />.

The `data()` hook can only be used for fetching the initial data of the page. For other use cases, such as data mutations and pagination data, use a data tool.

### Tools

Some data-fetching tools have Vike extensions that enable your components to fetch their initial data:
 - [`vike-react-query`](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-react">`vike-react`</Link>
 - [`vike-vue-query`](https://github.com/vikejs/vike-vue/tree/main/packages/vike-vue-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-vue">`vike-vue`</Link>
 - [`vike-solid-query`](https://github.com/vikejs/vike-solid/tree/main/packages/vike-solid-query#readme) - [TanStack Query](https://tanstack.com/query) integration for <Link href="/vike-solid">`vike-solid`</Link>
 - 🚧 `vike-react-telefunc` - [Telefunc](https://telefunc.com/) integration for <Link href="/vike-react">`vike-react`</Link>

> Instead of using the `+data` hook, you can then use any of your components to fetch data, including your <Link href="/Layout">`<Layout>` components</Link>.


## Data mutation & subsequent data

For data mutation and subsequent data fetching (such as pagination data), use a data tool.

### RPC

We generally recommend using RPC. It's simple, flexible, and performant.

For a list of RPC tools, see <Link href="/RPC" />.

### API routes

A common alternative to RPC is to use API routes, see <Link href="/api-routes" />.

### GraphQL

For large teams, it may make sense to use GraphQL instead of RPC.

With Vike, you can manually integrate GraphQL tools yourself, giving you complete control over integration:

- <Link href="/apollo-graphql" />
- <Link href="/relay" />
- <Link href="/urql" />

> In addition to manual integration, [you will soon](https://github.com/vikejs/vike/issues/1715) have the option to use <Link href="/extensions">Vike extensions</Link> for automatic integration.


## Pre-rendering (SSG)

For <Link href="/pre-rendering">pre-rendered pages / SSG apps</Link>, in order to fetch dynamic data from an external server, make sure to load and execute `data()` only on the client-side, see <Link href="/data#environment" />.


## Global data

A common use case is to fetch global data that is needed by all pages. (For example i18n data.)

You can <Link href="/pageContext#custom">add your initial data to `pageContext` at `renderPage()`</Link>.

The <Link href="/pageContext">`pageContext` object is accessible from any Vike hook and any UI component</Link>, thus you can access your initialization data there as well.

If you use <Link href="/pre-rendering">pre-rendering</Link> then see the workaround described at [#962 - New hook `onBoot()`](https://github.com/vikejs/vike/issues/962).


## State management

For managing complex UI state logic, you can use a store (Redux/Pinia/Zustand/...).

When using a store, all fetched data, including the initial data, is typically managed by the store. We recommend using an extension for automatic integration.

### Extensions

<Link href="/extensions">Vike extensions</Link> for state management tools:

- [`vike-vue-pinia`](https://github.com/vikejs/vike-vue/tree/main/packages/vike-vue-pinia)

> [Contributions welcome to create extensions](https://github.com/vikejs/vike/issues/1715).

### Custom integration

For complete control over integration, instead of using an extension, you can manually integrate a store yourself. See <Link href="/stores" />.



## See also

- <Link href="/data" />
- <Link href="/useData" />
- <Link href="/RPC" />
- <Link href="/api-routes" />
